<script setup lang="ts">
  import { PropType, ref, watch } from 'vue'
  import { ChildFormConfig, CustomChildFormFieldVal, DataConnectTable } from '../../hooks/types'
  import CustomInput from './CustomInput.vue'
  import CustomTextarea from './CustomTextarea.vue'
  import CustomSingleSelect from './CustomSingleSelect.vue'
  import CustomMultipleSelect from './CustomMultipleSelect.vue'
  import CustomDateTime from './CustomDateTime.vue'
  import CustomFileUpload from './CustomFileUpload.vue'
  import CustomDataConnect from './custom-data-connect/Index.vue'
  import _ from 'lodash'
  import { ElMessageBox, TableInstance } from 'element-plus'
  import { v4 as uuidv4 } from 'uuid'

  defineOptions({
    name: 'OrderCustomFormChildForm',
  })

  const props = defineProps({
    fieldList: {
      type: Array as PropType<Array<ChildFormConfig>>,
      required: true,
    },
    disabled: {
      type: Boolean,
      default: () => false,
    },
  })

  const modelValue = defineModel<Array<Record<string, CustomChildFormFieldVal>>>('modelValue', {
    default: [],
  })
  const selectedList = ref<Array<Record<string, CustomChildFormFieldVal>>>([])
  const _fieldList = ref<Array<ChildFormConfig>>([])
  const fieldDelPopoverVisibleList = ref<Array<boolean>>([])
  const tableInstance = ref<TableInstance | null>(null)

  /**
   * 表单关联数据选择事件
   * @param {ChildFormConfig} field - 字段对象
   * @param {DataConnectTable} selectData - 选择的数据
   */
  const handleFormCustomDataConnectChange = (
    field: ChildFormConfig,
    selectData: DataConnectTable,
    tableRowIndex: number,
  ) => {
    if (field.dataConnectConfig.selectMode === 2) {
      selectData.forEach((data) => {
        field.dataConnectConfig.fillRules.forEach((fillRule) => {
          if (fillRule.fillMode === 2) {
            modelValue.value[tableRowIndex][fillRule.toFieldId] = {
              id: uuidv4(),
              inputVal: data[fillRule.fromField],
              textareaVal: '',
              singleSelectVal: '',
              multipleSelectVal: [],
              datetimeVal: {
                date: '',
                dateTime: '',
                time: '',
                timeRange: {
                  date: '',
                  startTime: '',
                  endTime: '',
                },
              },
              dataConnectVal: '',
              fileUploadVal: [],
              isFixed: false,
            }
          }
        })
      })
      return
    }

    selectData.forEach((data, dataIndex) => {
      const result: Record<string, CustomChildFormFieldVal> = {}

      field.dataConnectConfig.fillRules.forEach((fillRule) => {
        if (fillRule.fillMode === 2) {
          result[fillRule.toFieldId] = {
            id: uuidv4(),
            inputVal: data[fillRule.fromField],
            textareaVal: '',
            singleSelectVal: '',
            multipleSelectVal: [],
            datetimeVal: {
              date: '',
              dateTime: '',
              time: '',
              timeRange: {
                date: '',
                startTime: '',
                endTime: '',
              },
            },
            dataConnectVal: '',
            fileUploadVal: [],
            isFixed: false,
          }
        }
      })

      result[field.id] = {
        id: uuidv4(),
        inputVal: '',
        textareaVal: '',
        singleSelectVal: '',
        multipleSelectVal: [],
        datetimeVal: {
          date: '',
          dateTime: '',
          time: '',
          timeRange: {
            date: '',
            startTime: '',
            endTime: '',
          },
        },
        dataConnectVal: data.id,
        fileUploadVal: [],
        isFixed: false,
      }

      fieldDelPopoverVisibleList.value.push(false)

      const tableRow = modelValue.value[dataIndex + tableRowIndex]
      if (!tableRow) {
        modelValue.value.push(result)
        return
      }

      let isTableRowFixed = true
      for (const key in tableRow) {
        if (!tableRow[key].isFixed) {
          isTableRowFixed = false
        }
      }

      if (isTableRowFixed) {
        modelValue.value.splice(dataIndex + tableRowIndex, 1, result)
      } else {
        modelValue.value.splice(dataIndex + tableRowIndex, 0, result)
      }
    })
  }

  /**
   * 表格行删除按钮点击事件
   * @param {number} rowIndex - 行索引
   */
  const handleConfirmRemoveClick = (rowIndex: number) => {
    modelValue.value.splice(rowIndex, 1)
  }

  const handleFormCustomDataConnectSelectDataClick = (
    tableRowIndex: number,
    fieldIndex: number,
  ) => {
    let isAllFieldFixed = true
    for (const key in modelValue.value[tableRowIndex]) {
      if (!modelValue.value[tableRowIndex][key].isFixed) {
        isAllFieldFixed = false
      }
    }

    if (!isAllFieldFixed) {
      _fieldList.value[fieldIndex].dataConnectConfig.selectMode = 2
    }
  }

  const onAddTableRow = () => {
    const result: Record<string, CustomChildFormFieldVal> = {}
    props.fieldList.forEach((field) => {
      result[field.id] = {
        id: uuidv4(),
        inputVal: '',
        textareaVal: '',
        singleSelectVal: '',
        multipleSelectVal: [],
        datetimeVal: {
          date: '',
          dateTime: '',
          time: '',
          timeRange: {
            date: '',
            startTime: '',
            endTime: '',
          },
        },
        dataConnectVal: '',
        fileUploadVal: [],
        isFixed: true,
      }
    })
    modelValue.value.push(result)
    fieldDelPopoverVisibleList.value.push(false)
  }

  const handleRemoveClick = (
    tableRow: Record<string, CustomChildFormFieldVal>,
    tableRowIndex: number,
  ) => {
    let isAllFieldFixed = true
    for (const key in tableRow) {
      if (!tableRow[key].isFixed) {
        isAllFieldFixed = false
      }
    }
    if (!isAllFieldFixed) {
      fieldDelPopoverVisibleList.value[tableRowIndex] = true
      return
    }

    modelValue.value.splice(tableRowIndex, 1)
  }

  const handleTableSelectionChange = (
    selection: Array<Record<string, CustomChildFormFieldVal>>,
  ) => {
    selectedList.value = selection
  }

  const onMultipleDelClick = () => {
    if (selectedList.value.length <= 0) {
      return
    }

    ElMessageBox({
      title: '提示',
      message: '确定要删除选中的数据吗，删除后无法恢复',
      autofocus: false,
      showCancelButton: true,
      type: 'error',
      beforeClose(action, instance, done) {
        if (action === 'confirm') {
          selectedList.value.forEach((data) => {
            const index = modelValue.value.findIndex((item) => _.isEqual(data, item))
            if (index !== 1) {
              modelValue.value.splice(index, 1)
            }
          })
          done()
          return
        }

        done()
      },
    })
  }

  const onCancelOperateClick = () => {
    if (tableInstance.value) {
      tableInstance.value.clearSelection()
      selectedList.value.length = 0
    }
  }

  watch(
    () => props.fieldList,
    (value) => {
      const result: Record<string, CustomChildFormFieldVal> = {}
      value.forEach((field) => {
        result[field.id] = {
          id: uuidv4(),
          inputVal: '',
          textareaVal: '',
          singleSelectVal: '',
          multipleSelectVal: [],
          datetimeVal: {
            date: '',
            dateTime: '',
            time: '',
            timeRange: {
              date: '',
              startTime: '',
              endTime: '',
            },
          },
          dataConnectVal: '',
          fileUploadVal: [],
          isFixed: true,
        }
      })

      if (Object.values(modelValue.value).length <= 0) {
        modelValue.value = [result]
      }
      _fieldList.value = _.cloneDeep(value).map((item) => {
        item.dataConnectConfig.selectMode = 1
        return item
      })
      fieldDelPopoverVisibleList.value = [false]
    },
    { immediate: true, deep: true },
  )
</script>

<template>
  <div class="order-custom-form-child-form">
    <div class="container">
      <el-table
        ref="tableInstance"
        :data="modelValue"
        :border="true"
        :max-height="500"
        @selection-change="handleTableSelectionChange"
      >
        <el-table-column
          v-if="!props.disabled"
          type="selection"
          width="50"
          fixed="left"
          :align="'center'"
        />
        <el-table-column type="index" label="序号" width="50" fixed="left" :align="'center'" />
        <el-table-column
          v-for="(field, fieldIndex) in _fieldList"
          :key="fieldIndex"
          min-width="140"
          :label="field.label"
        >
          <template #default="{ row, $index }">
            <!-- 单行输入 -->
            <custom-input
              v-if="field.fieldType === 'input' && row[field.id]"
              v-model="row[field.id].inputVal"
              :disabled="props.disabled"
              :amount-max="field.inputConfig.amountMax"
              :maxlength="field.inputConfig.maxLength"
              :number-max="field.inputConfig.numberMax"
              :placeholder="field.inputConfig.placeholder"
            />

            <!-- 多行输入 -->
            <custom-textarea
              v-if="field.fieldType === 'textarea' && row[field.id]"
              v-model="row[field.id].textareaVal"
              :disabled="props.disabled"
              :maxlength="field.textareaConfig.maxLength"
              :placeholder="field.textareaConfig.placeholder"
            />

            <!-- 下拉单选 -->
            <custom-single-select
              v-if="field.fieldType === 'single-select' && row[field.id]"
              v-model="row[field.id].singleSelectVal"
              :disabled="props.disabled"
              :placeholder="field.singleSelectConfig.placeholder"
              :options="field.singleSelectConfig.options"
            />

            <!-- 下拉多选 -->
            <custom-multiple-select
              v-if="field.fieldType === 'multiple-select' && row[field.id]"
              v-model="row[field.id].multipleSelectVal"
              :disabled="props.disabled"
              :placeholder="field.multipleSelectConfig.placeholder"
              :options="field.multipleSelectConfig.options"
            />

            <!-- 日期时间 -->
            <custom-date-time
              v-if="field.fieldType === 'date-time' && row[field.id]"
              v-model="row[field.id].datetimeVal"
              :disabled="props.disabled"
              :datetime-type="field.dateTimeConfig.dateTimeType"
              :placeholder="field.dateTimeConfig.placeholder"
            />

            <!-- 文件上传 -->
            <custom-file-upload
              v-if="field.fieldType === 'file-upload' && row[field.id]"
              v-model="row[field.id].fileUploadVal"
              :disabled="props.disabled"
              :num="field.fileUploadConfig.num"
              :size="field.fileUploadConfig.size"
              :upload-type="field.fileUploadConfig.type"
            />

            <!-- 关联数据 -->
            <custom-data-connect
              v-if="field.fieldType === 'data-connect' && row[field.id]"
              :disabled="props.disabled"
              :data-type="field.dataConnectConfig.type"
              :field-list="field.dataConnectConfig.fieldList"
              :select-mode="field.dataConnectConfig.selectMode"
              :selected-row-ids="[row[field.id].dataConnectVal]"
              @change="(selectData: DataConnectTable) => handleFormCustomDataConnectChange(field, selectData, $index)"
              @select-data-click="handleFormCustomDataConnectSelectDataClick($index, fieldIndex)"
            />
          </template>
        </el-table-column>
        <el-table-column v-if="!props.disabled" label="操作" :width="70" fixed="right">
          <template #default="{ row, $index }">
            <el-popover
              :visible="fieldDelPopoverVisibleList[$index]"
              :width="200"
              placement="bottom-end"
              trigger="click"
            >
              <template #reference>
                <h-link type="error" @click="handleRemoveClick(row, $index)">移除</h-link>
              </template>

              <div class="field-del-panel">
                <div class="title">提示</div>
                <div class="content">这行已经选择了数据，确定要删除吗？</div>
                <div class="footer">
                  <h-plain-button
                    type="error"
                    :height="18"
                    :width="36"
                    @click="handleConfirmRemoveClick($index)"
                    >确定</h-plain-button
                  >
                  <h-button
                    :height="18"
                    :width="36"
                    @click="fieldDelPopoverVisibleList[$index] = false"
                    >取消</h-button
                  >
                </div>
              </div>
            </el-popover>
          </template>
        </el-table-column>
      </el-table>

      <div v-if="!props.disabled" class="footer">
        <template v-if="selectedList.length <= 0">
          <h-link @click="onAddTableRow">+ 添加</h-link>
        </template>
        <template v-else>
          <h-button @click="onCancelOperateClick">取消操作</h-button>
          <h-plain-button type="error" @click="onMultipleDelClick">批量删除</h-plain-button>
        </template>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
  .order-custom-form-child-form {
    width: 100%;

    .container {
      .footer {
        padding: 8px 0 0 24px;
        display: flex;
        column-gap: 8px;
      }
    }
  }

  .field-del-panel {
    display: flex;
    flex-direction: column;

    .title {
      font-weight: bold;
      color: #000;
    }

    .footer {
      display: flex;
      justify-content: flex-end;
      margin-top: 8px;
      column-gap: 4px;
    }
  }
</style>
